package com.xiaojie.importdata.handler.impl;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.xiaojie.context.DataInfoContext;
import com.xiaojie.importdata.AutoGenerateField;
import com.xiaojie.importdata.handler.AbstractReplaceFieldValueHandler;
import com.xiaojie.parse.model.DataModel;
import com.xiaojie.parse.model.Table;
import com.xiaojie.toolkits.FieldNameUtil;

import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 根据配置文件中字段值自动生成规则替换为新的值
 *
 * @ClassName ReplaceAtuoGenerateFieldValue
 * @Author wangye
 * @Date 2022/3/13
 **/
public class ReplaceAtuoGenerateFieldValue extends AbstractReplaceFieldValueHandler {


    private final static Map<String, AutoGenerateField> AUTO_GENERATE_FIELD_MAP = Maps.newHashMap();

    /**
     * 根据自定义实现类生成字段值，自定义配置优于全局配置
     * 实现接口{@link AutoGenerateField}
     *
     * @param tableName
     * @param table
     * @param rowData
     * @Author: wangye
     * @Date: 2022/3/13 11:02
     * @return:
     **/
    @Override
    public void replaceFieldValue(String tableName, Table table, Map rowData) {
        DataModel dataModel = DataInfoContext.get().getDataModelInfo();

        Map<String, Set<String>> refFieldsMap = dataModel.getRefFieldsMap();

//        Settings globalSettings = dataModel.getSettings();

//        Map<String, String> globalAutoGenerateFieldsMap = Optional.ofNullable(globalSettings.getAutoGenerateFields())
//                .orElse(Maps.newHashMap());

        Map<String, String> autoGeneralFieldsMap = Optional.ofNullable(table.getSettings())
                .flatMap(setting -> Optional.ofNullable(setting.getAutoGenerateFields()))
                .orElse(Maps.newHashMap());
        Map<String, Map<String, Map>> refFieldDataMap = DataInfoContext.get().getRefFieldValueMap();
//        //获取全局要自动生产字段配置
//        Map<String, String> autoGenerateFilesMap = new HashMap<>(globalAutoGenerateFieldsMap);
//        //全局为空/表级自动生成不为空 则覆盖配置为 表级自动生产字段配置
//        //表级配置会覆盖全局配置（字段级别）
//        if (tableSettings != null && tableSettings.getAutoGenerateFields() != null) {
//            autoGenerateFilesMap.putAll(tableSettings.getAutoGenerateFields());
//        }

        //上下文中的 「新旧对照关系」
        //获取新旧数据对应关系容器
        Map<String, Map> tableCorrespondFieldsMap = Optional.ofNullable(
                        DataInfoContext.get().getCorrespondDataTableFieldMap()
                                .get(tableName))
                .orElse(Maps.newHashMap());
        //优先获取表级，没有获取全局的
        //获取表中需要保留新旧数据关系的字段名，通过表级配置和全局配置
//        List<String> correspondDataFieldNames = getCorrespondFieldNames(table.getSettings(), globalSettings);
        List<String> correspondDataFieldNames = Optional.ofNullable(table.getSettings()).flatMap(s -> Optional.ofNullable(s.getCorrespondDataFields()))
                .orElse(Lists.newArrayList())
                .stream().map(fieldName -> FieldNameUtil.convert(fieldName)).collect(Collectors.toList());

        //需要自动生成的字段 如果被其他表关联 则会放入refFieldDataMap
        autoGeneralFieldsMap.entrySet().stream()
                //过滤 没有查询到的 字段名
                .filter(fieldEntry -> rowData.containsKey(FieldNameUtil.convert(fieldEntry.getKey())))
                .forEach(fieldEntry -> {
                    //字段名
                    String fieldName = FieldNameUtil.convert(fieldEntry.getKey());
                    //生成类全路径
                    String classPath = fieldEntry.getValue();
                    //表可以单独设置字段不自动生成
                    if (!"false".equals(classPath)) {
                        //将实现了AutoGenerateField接口的类放入MAP中，这里通过类全路径获取
                        AutoGenerateField autoGenerateField = AUTO_GENERATE_FIELD_MAP.get(classPath);
                        //这里还做了判断
                        if (autoGenerateField == null) {
                            try {
                                Class<?> clazz = Class.forName(classPath);
                                autoGenerateField = (AutoGenerateField) clazz.newInstance();
                            } catch (Exception e) {
                                throw new RuntimeException(e);
                            }
                            AUTO_GENERATE_FIELD_MAP.put(classPath, autoGenerateField);
                        }
                        Object newFieldValue = autoGenerateField.get();
                        buildFieldRefDataMap(refFieldDataMap, tableName, rowData.get(fieldName), refFieldsMap, fieldName, newFieldValue);
                        //保存单个字段新旧数据对应关系
                        if (correspondDataFieldNames.contains(fieldName)) {
                            Map correspondFieldMap = Optional.ofNullable(tableCorrespondFieldsMap.get(fieldName)).orElse(Maps.newHashMap());
                            correspondFieldMap.put(rowData.get(fieldName), newFieldValue);
                            tableCorrespondFieldsMap.put(fieldName, correspondFieldMap);
                        }
                        // 设置新值
                        rowData.put(fieldName, newFieldValue);
                    }
                });

        //将新旧数据对应关系放入上下文
        DataInfoContext.get().getCorrespondDataTableFieldMap().put(tableName, tableCorrespondFieldsMap);
    }

}
